/**
 * 
 */
package com.aspire.android.heliar.raw.mms;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.util.LinkedList;
import java.util.List;

import com.aspire.android.heliar.Heliar;
import com.aspire.android.heliar.utils.ContextFactory;

import android.database.Cursor;
import android.net.Uri;
import android.util.Log;

/**
 * @author panglei
 * 
 */
public class MMSParser {

	public static final String CONTENT_PROVIDER_MMS_URI = "content://mms";
	public static final String CONTENT_PROVIDER_MMS_PART = "part";
	public static final String CONTENT_PROVIDER_MMS_ATTACHMENT_URI = "content://mms/part/";

	public static final String FIELD_MMS_ID = "_id";
	public static final String FIELD_MMS_SUBJECT = "sub";
	public static final String FIELD_MMS_THREAD_ID = "thread_id";
	public static final String FIELD_MMS_DATE = "date";

	public static final String FIELD_MMS_PART_ID = "_id";
	public static final String FIELD_MMS_CID = "cid";
	public static final String FIELD_MMS_CONTENT_TYPE = "ct";
	public static final String FIELD_MMS_TEXT = "text";

	public static final String FIELD_MMS_ADDRESS = "address";
	public static final String FIELD_MMS_CONTACT_ID = "contact_id";
	public static final String FIELD_MMS_CHARSET = "charset";
	public static final String FIELD_MMS_TYPE = "type";
	public static final String FIELD_MMS_ADDR_PATH = "addr";

	public static final String ENCODE_ISO88591 = "iso-8859-1";
	public static final String ENCODE_UTF_8 = "UTF-8";

	public static final String CONTENT_TYPE_SMIL = "application/smil";
	public static final String CONTENT_TYPE_TEXT = "text/plain";
	public static final String CONTENT_TYPE_JPG = "image/jpeg";
	public static final String CONTENT_TYPE_GIF = "image/gif";
	public static final String CONTENT_TYPE_AMR = "";
	public static final String CONTENT_TYPE_MIDI = "";

	public static void delete(String id) {
		ContextFactory
				.getInstance()
				.getContentResolver()
				.delete(Uri.parse(CONTENT_PROVIDER_MMS_URI + "/" + id), null,
						null);
	}

	public static MMS loadMMS(int id) {

		MMS mms = null;
		Cursor cur = ContextFactory
				.getInstance()
				.getContentResolver()
				.query(Uri.parse(CONTENT_PROVIDER_MMS_URI + "/" + id), null,
						null, null, null);
		if (cur.moveToFirst()) {
			try {
				String subject = new String(cur.getString(
						cur.getColumnIndex(FIELD_MMS_SUBJECT)).getBytes(
						ENCODE_ISO88591), ENCODE_UTF_8);
				int threadId = cur.getInt(cur
						.getColumnIndex(FIELD_MMS_THREAD_ID));
				int date = cur.getInt(cur.getColumnIndex(FIELD_MMS_DATE));

				mms = new MMS();
				mms.setId(id);
				mms.setThreadId(threadId);
				mms.setSubject(subject);
				mms.setDate(date);
				mms.setAddress(MMSParser.parseMMSAddress(id));

				parseMMS(id, mms);

			} catch (UnsupportedEncodingException e) {
				Log.d(Heliar.LOG_TAG, e.getMessage(), e);
			}

		}
		return mms;

	}

	public static void parseMMS(int id, MMS mms) {
		Cursor curPart = ContextFactory
				.getInstance()
				.getContentResolver()
				.query(Uri.parse(CONTENT_PROVIDER_MMS_URI + "/" + id + "/"
						+ CONTENT_PROVIDER_MMS_PART), null, null, null, null);

		if (curPart.moveToFirst()) {

			do {
				try {
					int partId = curPart.getInt(curPart
							.getColumnIndex(FIELD_MMS_PART_ID));
					String cid = curPart.getString(
							curPart.getColumnIndex(FIELD_MMS_CID))
							.toLowerCase();
					String contentType = curPart.getString(
							curPart.getColumnIndex(FIELD_MMS_CONTENT_TYPE))
							.toLowerCase();
					Log.d(Heliar.LOG_TAG, "Parse cid = " + cid);
					if (CONTENT_TYPE_SMIL.equals(contentType)) {
						// TODO Parse smil
						Log.d(Heliar.LOG_TAG, "Parse smil file cid: " + cid);

					} else {
						// Parse frame content
						try {
							if (CONTENT_TYPE_TEXT.equals(contentType)) {
								// Parse text frame
								Log.d(Heliar.LOG_TAG, "Parse text cid: " + cid);

								MMSTextFrame frame = new MMSTextFrame();
								frame.setContentType(contentType);
								frame.setCid(cid);
								frame.setText(curPart.getString(curPart
										.getColumnIndex(FIELD_MMS_TEXT)));
								mms.addMMSFrame(frame);
							} else if (CONTENT_TYPE_JPG.equals(contentType)
									|| CONTENT_TYPE_GIF.equals(contentType)) {
								// Parse image frame
								Log.d(Heliar.LOG_TAG, "Parse image cid: " + cid);

								MMSImageFrame frame = new MMSImageFrame();
								frame.setContentType(contentType);
								frame.setCid(cid);
								frame.createBitmap(openAttachment(partId));
								mms.addMMSFrame(frame);

							} else if (CONTENT_TYPE_AMR.equals(contentType)
									|| CONTENT_TYPE_MIDI.equals(contentType)) {
								// TODO Parse sound frame

							}
						} catch (FileNotFoundException e) {
							e.printStackTrace();
							Log.e(Heliar.LOG_TAG, e.getMessage(), e);
						} catch (IOException e) {
							e.printStackTrace();
							Log.e(Heliar.LOG_TAG, e.getMessage(), e);
						} catch (NullPointerException e) {
							e.printStackTrace();
							Log.e(Heliar.LOG_TAG, e.getMessage(), e);
						}

					}
				} catch (NullPointerException e) {
					e.printStackTrace();
					Log.e(Heliar.LOG_TAG, e.getMessage(), e);
				}
			} while (curPart.moveToNext());
		}
	}

	public static String parseMMSAddress(int mmsId) {

		String add = "";
		final String[] projection = new String[] { FIELD_MMS_ADDRESS,
				FIELD_MMS_CONTACT_ID, FIELD_MMS_CHARSET, FIELD_MMS_TYPE };
		final String selection = "type=137";

		Uri.Builder builder = Uri.parse(CONTENT_PROVIDER_MMS_URI).buildUpon();
		builder.appendPath(String.valueOf(mmsId)).appendPath(
				FIELD_MMS_ADDR_PATH);

		Cursor cursor = ContextFactory.getInstance().getContentResolver()
				.query(builder.build(), projection, selection, null, null);

		if (cursor.moveToFirst()) {
			add = cursor.getString(0);
		}

		return add;

	}

	private static InputStream openAttachment(int partId)
			throws FileNotFoundException {
		Uri partURI = Uri.parse(CONTENT_PROVIDER_MMS_ATTACHMENT_URI + partId);
		return ContextFactory.getInstance().getContentResolver()
				.openInputStream(partURI);
	}

	public static List<MMS> listMMS(boolean isLazy) {

		List<MMS> list = new LinkedList<MMS>();

		Cursor cur = ContextFactory
				.getInstance()
				.getContentResolver()
				.query(Uri.parse(CONTENT_PROVIDER_MMS_URI), null, null, null,
						null);

		try {
			if (cur.moveToFirst()) {

				do {
					try {
						int id = cur.getInt(cur.getColumnIndex(FIELD_MMS_ID));
						String subject = new String(cur.getString(
								cur.getColumnIndex(FIELD_MMS_SUBJECT))
								.getBytes(ENCODE_ISO88591), ENCODE_UTF_8);
						int threadId = cur.getInt(cur
								.getColumnIndex(FIELD_MMS_THREAD_ID));
						int date = cur.getInt(cur
								.getColumnIndex(FIELD_MMS_DATE));

						MMS mms = new MMS();
						mms.setId(id);
						mms.setThreadId(threadId);
						mms.setSubject(subject);
						mms.setDate(date);
						mms.setAddress(MMSParser.parseMMSAddress(id));

						if (!isLazy) {
							parseMMS(id, mms);
						}

						list.add(mms);
					} catch (RuntimeException e) {
						Log.e(Heliar.LOG_TAG, e.getMessage(), e);
					}

				} while (cur.moveToNext());
			}
		} catch (UnsupportedEncodingException e) {
			Log.e(Heliar.LOG_TAG, e.getMessage(), e);
			e.printStackTrace();
		}
		return list;
	}

	public static List<MMS> listMMS(MMSParserFilter filer) {
		return null;
	}

}
